package cn.pconline.autoclub.service;

import cn.pconline.autoclub.entity.Comment;
import cn.pconline.autoclub.entity.User;
import cn.pconline.autoclub.util.DateUtils;
import cn.pconline.autoclub.util.Pager;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang.StringUtils;
import org.gelivable.dao.GeliDao;
import org.gelivable.dao.GeliOrm;
import org.gelivable.dao.SqlBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;

/**
 *
 * @author ppc
 */
public class CommentService {

    @Autowired
    private GeliDao geliDao;
    @Autowired
    GeliOrm geliOrm;
    @Autowired
    private PagerService pagerService;
    @Autowired
    JdbcTemplate jdbcTemplate;
    private static final Logger log = LoggerFactory.getLogger(ClubService.class);

    /**
     * 留言
     *
     * @param object
     * @return
     */
    public long addComment(Comment comment) {
        return this.geliDao.create(comment);
    }

    /**
     * 删除留言
     *
     * @param object
     * @param id
     * @return
     */
    public int deleteComment(long clubId, long id) {
        Comment comment = this.geliDao.find(Comment.class, clubId, id);
        if (comment == null) {
            return 0;
        }
        if (comment.getReplyId() != 0) {
            Comment c = this.geliDao.find(Comment.class, clubId, comment.getReplyId());
            c.setReplyNum(c.getReplyNum() - 1);//减去回复数
            this.geliDao.update(c);
        }else if (comment.getReplyId() == 0){
        	//当删除留言为主题是，批量修改回复状态
        	this.deleteReplayByCid(comment.getCommentId(), clubId);
        }
        comment.setStatus(Comment.STATUS_DELETE);
        comment.setUpdateDate(DateUtils.getNow());
        this.geliDao.update(comment);
        return 1;
    }
    /**
     * 根据留言主题ID批量修改回复状态
     * @param commentId
     * @param clubId
     * @return
     */
    public int deleteReplayByCid(long commentId,long clubId){
    	if(commentId<1){
    		return 0;
    	}
    	SqlBuilder sql = new SqlBuilder();
    	sql.appendSql(" update ").appendSql(geliOrm.getTableName(Comment.class,clubId));
    	sql.appendSql(" set status = ? where main_comment_id = ?");
    	return jdbcTemplate.update(sql.getSql(), Comment.STATUS_DELETE, commentId);
    }

    /**
     * 回复留言
     *
     * @param object
     * @return
     */
    public long replyComment(Comment comment, long clubId) {
        try {
            Comment c = this.geliDao.find(Comment.class, clubId, comment.getReplyId());
            if (c.getReplyId() > 0) {
                return 0;
            }
            if (c != null && c.getStatus() != -1) {
                long id = this.geliDao.create(comment);
                int num = c.getReplyNum();
                c.setReplyNum(num + 1);
                this.geliDao.update(c);
                return id;
            } else {
                return 0;
            }
        } catch (DataAccessException ex) {
        	log.error("=====回复失败====\n" + ex.getMessage());
            return 0;
        }

    }

    /**
     * 加载留言
     *
     * @param clubId
     * @param pageNo
     * @param pageSize
     * @return
     */
    public JSONObject loadComment(long clubId, int pageNo, int pageSize) {
        Pager<Comment> pager = loadPager(clubId,0, pageNo, pageSize);
        JSONObject object = new JSONObject();
        List<Comment> list = pager.getResultList();
        JSONArray array = getCommentJSON(list);
        object.put("pageNo", pageNo);
        object.put("pageSize", pageSize);
        object.put("total", pager.getTotal());
        object.put("totalCount", pager.getPageCount());
        object.put("result", array);
        object.put("code", 0);
        return object;
    }

    public JSONArray getCommentJSON(List<Comment> list) {
        JSONArray array = new JSONArray();
        if (list != null) {
            for (Comment c : list) {
                array.add(getCommentJSON(c));
            }
        }
        return array;
    }

    /**
     * 加载回复
     *
     * @param commentId 留言ID
     * @return
     */
    public List<Comment> loadReply(long commentId, long clubId) {
        return listReplyByCommentId(commentId, clubId);
    }

    /**
     * 逻辑删除某会员在某车友会下的所有留言（这个操作没有减少分数）
     *
     * @param userId
     * @param clubId
     */
    public void batchDeleteComment(long userId, long clubId) {
        String baseSql = "UPDATE %s SET status = %s WHERE create_by = %s and club_id = %s";
        String sql = String.format(baseSql, "ac_comment_" + clubId % 10, Comment.STATUS_DELETE, userId, clubId);
        String[] sqls = new String[1];
        sqls[0] = sql;
        geliDao.getJdbcTemplate().batchUpdate(sqls);
    }

    /**
     * 删除回复
     *
     * @param id 要删除的回复ID
     * @return
     */
    public int deleteReply(long clubId, long id) {
        Comment comment = this.geliDao.find(Comment.class, clubId, id);
        if (comment != null) {
            if (comment.getStatus() == -1) {
                return 1;
            }
            comment.setStatus(Comment.STATUS_DELETE);
            comment.setUpdateDate(DateUtils.getNow());
            this.geliDao.update(comment);
            Comment pComment = this.geliDao.find(Comment.class, comment.getReplyId());
            pComment.setReplyNum(pComment.getReplyNum() - 1);
            this.geliDao.update(pComment);
            return 1;
        }
        return 0;
    }

    private List<Comment> listReplyByCommentId(long commentId, long clubId) {
        Comment comment = this.geliDao.find(Comment.class, clubId, commentId);
        SqlBuilder sql = new SqlBuilder();
        sql.appendSql("select comment_id from ").appendSql(getTableName(comment.getClubId()))
                .appendSql(" where club_id=").appendValue(comment.getClubId())//用club缩小过滤范围，而且能用上索引
                .appendSql(" and main_comment_id=").appendValue(commentId)
                .appendSql(" and status>=0  order by create_at limit 500");
        List<Comment> comments = this.geliDao.list(Comment.class, comment.getClubId(), sql.getSql(), sql.getValues());
        comments = loadCommentUser(comments);
        return comments;
    }

    public Comment getCommentById(long clubId, long id) {
        Comment c;
        try {
            c = this.geliDao.find(Comment.class, clubId, id);
        } catch (DataAccessException ex) {
            return null;
        }
        return c;
    }
    /**
     * 根据车友会获取留言分页列表
     * @param clubId
     * @param pageNo
     * @param pageSize
     * @return
     */
    public Pager<Comment> loadPager(long clubId,long userId, int pageNo, int pageSize) {
        SqlBuilder sql = new SqlBuilder();
        sql.appendSql("select comment_id from ").appendSql(getTableName(clubId));
        sql.appendSql(" where club_id=").appendValue(clubId);
        if(userId>0){
        	sql.appendSql(" and create_by=").appendValue(userId);
        }
        sql.appendSql(" and main_comment_id=0 and status=1 order by create_at desc");
        
        Pager<Comment> pager = null;
        try {
            pager = pagerService.pager(Comment.class,clubId, sql, pageNo, pageSize);
            pager.setResultList(loadCommentUser(pager.getResultList()));
            pager.setResultList(loadCommentReply(pager.getResultList(),clubId));
        } catch (DataAccessException ex) {
        }
        return pager;
    }

    private List<Comment> loadCommentUser(List<Comment> comments) {
        try {
            if (comments != null && comments.size() > 0) {
                long ids[] = new long[comments.size()];
                for (int i = 0; i < comments.size(); i++) {

                    long id = comments.get(i).getCreateBy();
                    if (id == 0) {
                        continue;
                    }
                    ids[i] = id;
                }
                List<User> users = this.geliDao.list(User.class, ids);
                for (int i = 0; i < comments.size(); i++) {
                    comments.get(i).setUser(users.get(i));
                }
            }
        } catch (DataAccessException ex) {
        }

        return comments;
    }

    public JSONObject getCommentJSON(Comment c) {
        JSONObject obj = new JSONObject();
        if (c.getUser() == null) {
            c.setUser(geliDao.find(User.class, c.getCreateBy()));
        }
        obj.put("commentId", c.getCommentId());
        obj.put("clubId", c.getClubId());
        obj.put("content", c.getContent());
        obj.put("createBy", c.getCreateBy());
        obj.put("createDate", DateUtils.formatDetail(c.getCreateDate()));
        obj.put("imgUrl", c.getImgUrl());
        JSONArray imgUrl1array = null;
        if (c.getImgUrl1() != null && !"".equals(c.getImgUrl1())) {
            imgUrl1array = new JSONArray();
            imgUrl1array.add(c.getImgUrl1());
            imgUrl1array.add(c.getImgUrl1x700());
        }
        obj.put("imgUrl1", imgUrl1array);
        JSONArray imgUrl2array = null;
        if (c.getImgUrl2() != null) {
            imgUrl2array = new JSONArray();
            imgUrl2array.add(c.getImgUrl2());
            imgUrl2array.add(c.getImgUrl2x700());
        }
        obj.put("imgUrl2", imgUrl2array);
        obj.put("isPic", c.getIsPic());
        obj.put("replyId", c.getReplyId());
        obj.put("replyNum", c.getReplyNum());
        obj.put("status", c.getStatus());
        obj.put("updateDate", DateUtils.formatDetail(c.getUpdateDate()));
        obj.put("userName", c.getUserName());
        JSONArray array = new JSONArray();
        if (c.getReplys() != null && !c.getReplys().isEmpty()) {
            for (Comment r : c.getReplys()) {
                array.add(getCommentJSON(r));
            }
        }

        obj.put("replys", array);
        return obj;
    }

    private String getTableName(long clubId) {
        return geliOrm.getTableName(Comment.class, clubId);
    }

    /**
     * 留言加载回复信息
     * @param list
     * @param clubId
     * @return
     */
    private List<Comment> loadCommentReply(List<Comment> list, long clubId) {
    	if(list!=null && !list.isEmpty()){
    		String ids = "";
            for (Comment c : list) {
            	ids+=c.getCommentId()+",";
//                c.setReplys(listReplyByCommentId(c.getCommentId(), clubId));
            }
            ids = ids.substring(0, ids.length()-1);
            if(StringUtils.isNotBlank(ids)){
            	SqlBuilder sql = new SqlBuilder();
            	sql.appendSql("select comment_id from ").appendSql(geliOrm.getTableName(Comment.class,clubId));
            	sql.appendSql(" where club_id=").appendValue(clubId);
                sql.appendSql(" and main_comment_id in ("+ids+")");
                sql.appendSql(" and status >= 0 ");
                sql.appendSql(" and censored >= 0 ");
                List<Comment> comments = this.geliDao.list(Comment.class, clubId, sql.getSql(), sql.getValues());
                if(comments!=null && !comments.isEmpty()){
                	comments = loadCommentUser(comments);
                	Map<Long,List<Comment>> map = new HashMap<Long, List<Comment>>();
                	for(Comment comment : comments){
                		if(map.get(comment.getReplyId())==null){
                			List<Comment> listReply = new ArrayList<Comment>();
                			listReply.add(comment);
                			map.put(comment.getReplyId(), listReply);
                		}else{
                			List<Comment> listR = map.get(comment.getReplyId());
                			listR.add(comment);
                			map.put(comment.getReplyId(), listR);
                		}
                	}
                	for(Comment listC : list){
                		listC.setReplys(map.get(listC.getCommentId()));
                	}
                }
            }
    	}
    	
    	
    	
        return list;
    }

    /**
     * 根据车友会ID统计留言数量
     *
     * @param clubId
     * @return
     */
    public int countByClubId(long clubId) {
        if (clubId < 1) {
            return 0;
        }
        SqlBuilder sql = new SqlBuilder();
        sql.appendSql(" select count(1) from ").appendSql(geliOrm.getTableName(Comment.class, clubId));
        sql.appendSql(" where club_id =").appendValue(clubId);
        sql.appendSql(" and status !=").appendValue(Comment.STATUS_DELETE);
        sql.appendSql(" and censored !=").appendValue(Comment.CENSORED_DELETE);
        return geliDao.count(sql.getSql(), sql.getValues());
    }

    /**
     * 根据用户ID查询留言
     * @param clubId
     * @param userId
     * @param pageNo
     * @param pageSize
     * @return 
     */
    public Pager<Comment> loadCommentByUser(long clubId, long userId, int pageNo, int pageSize) {
        if (clubId == 0) {
            return null;
        }
        SqlBuilder sql = new SqlBuilder();
        sql.appendSql("select * from ").appendSql(geliOrm.getTableName(Comment.class, clubId)).appendSql(" where create_by=").appendValue(userId).appendSql(" and main_comment_id=0").appendSql(" and status=").appendValue(Comment.STATUS_NORMAL).appendSql(" and club_id=").appendValue(clubId);
        String countSql = sql.getSql().replace("*", "count(1)");
        Pager<Comment> pager = new Pager<Comment>();
        try {
            List<Comment> comments = geliDao.page(Comment.class, clubId, sql.getSql(), pageNo, pageSize, sql.getValues());
            int total = geliDao.count(countSql, sql.getValues());
            pager.setTotal(total);
            pager.setPageNo(pageNo);
            pager.setPageSize(pageSize);
            pager.setResultList(comments);
        } catch (Exception ex) {
            return pager;
        }
        return pager;
    }
}
